﻿using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using SoftSource.Common;
using SoftSource.Timecard.Entry.Converters;
using SoftSource.Timecard.Web.Data;

namespace SoftSource.Timecard.Entry.Controls
{
    public sealed class CategoryComboBox : ComboBox
    {
        private PagedCollectionView source;

        public CategoryComboBox()
        {
            this.DefaultStyleKey = typeof(CategoryComboBox);

            Loaded += new RoutedEventHandler(CategoryComboBox_Loaded);
            this.SelectionChanged += new SelectionChangedEventHandler(CategoryComboBox_SelectionChanged);
        }

        void CategoryComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            CategorySummary category = this.SelectedItem as CategorySummary;
            if (category != null)
                this.CategoryID = category.CategoryID;
        }

        void CategoryComboBox_Loaded(object sender, RoutedEventArgs e)
        {
            if (App.Model != null)
            {
                int originalID = this.CategoryID;
                
                if (this.ItemsSource == null)
                    this.ItemsSource = App.Model.CategorySummaries.Entities;
                
                this.source = new PagedCollectionView(this.ItemsSource);
                this.source.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
                this.Filter = this.source.AttachFilter<CategorySummary>();

                this.Filter.Add(category =>
                    {
                        if (this.Active && !category.IsActive)
                        {
                            return false;
                        }
                        return true;
                    });

                this.DisplayMemberPath = "Name";
                this.ItemsSource = this.source;
                this.CategoryID = originalID;

                if (this.CategoryID != Category.InvalidCategoryID)
                    this.SelectedItem = App.Model.CategorySummaries.Entities.SingleOrDefault(c => c.CategoryID == this.CategoryID);

                Binding categoryBinding = new Binding("CategoryID");
                categoryBinding.Source = this;
                categoryBinding.Converter = new CategoryIDConverter();                
                categoryBinding.Mode = BindingMode.TwoWay;
                this.SetBinding(ComboBox.SelectedItemProperty, categoryBinding);
            }
        }

        private void RunFilters()
        {
            if (this.Filter != null)
                this.Filter.Refresh.TryInvoke();
        }

        #region Dependency Properties
        [Category("Timecard")]
        [Description("The ID of the current Category")]
        public int CategoryID
        {
            get { return (int)GetValue(CategoryIDProperty); }
            set { SetValue(CategoryIDProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ProjectID.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CategoryIDProperty =
            DependencyProperty.Register("CategoryID", typeof(int), typeof(CategoryComboBox), new PropertyMetadata(Category.InvalidCategoryID));


        [Category("Timecard")]
        [Description("Filters categories with custom predicates")]
        public Filter<CategorySummary> Filter
        {
            get { return (Filter<CategorySummary>)GetValue(FilterProperty); }
            set { SetValue(FilterProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Filter.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty FilterProperty =
            DependencyProperty.Register("Filter", typeof(Filter<CategorySummary>), typeof(CategoryComboBox), new PropertyMetadata(null));



        [Category("Timecard")]
        [Description("Filters categories that have been categorized as \'Active\'")]
        public bool Active
        {
            get { return (bool)GetValue(ActiveProperty); }
            set { SetValue(ActiveProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Active.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ActiveProperty =
            DependencyProperty.Register("Active", typeof(bool), typeof(CategoryComboBox), new PropertyMetadata(true, (sender, args) =>
            {
                CategoryComboBox cb = sender as CategoryComboBox;
                if (cb != null)
                    cb.RunFilters();
            }));
        #endregion Dependency Properties
    }
}
